package com.heima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.constant.LoginConstant;
import com.heima.exception.BaseException;
import com.heima.mapper.UserMapper;
import com.heima.pojo.dto.UserDto;
import com.heima.pojo.dto.UserSearchDto;
import com.heima.pojo.entity.User;
import com.heima.pojo.dto.LoginDto;
import com.heima.pojo.vo.LoginUserVo;
import com.heima.pojo.vo.UserSearchVo;
import com.heima.pojo.vo.UserVo;
import com.heima.service.UserService;
import com.heima.utils.JwtUtil;
import com.heima.utils.Md5Util;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    private final RedisTemplate redisTemplate;

    private Boolean checkPassword(String oldPassword,String databasePassword){
        String salt = databasePassword.substring(32);
        String one = Md5Util.MD5Lower(oldPassword);
        String res = Md5Util.MD5Lower(one+salt)+salt;
        return databasePassword.equals(res);
    }

    @Override
    public LoginUserVo login(LoginDto dto) {
        if(dto == null){
            //参数异常
            throw new BaseException("参数异常");
        }
        //1.是否输入了验证码
        if (!StringUtils.hasText(dto.getCode())){
            throw new BaseException("验证码为空");
        }
        //2.校验验证码
        String code = (String) redisTemplate.opsForValue().get(dto.getClientToken());
        if (code==null){
            throw new BaseException("验证码已过期");
        }
        if (!code.equals(dto.getCode().toLowerCase())){
            throw new BaseException("验证码错误");
        }
        //3.检验用户存不存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getLoginName,dto.getLoginName());
        User user = userMapper.selectByName(dto.getLoginName());
        if(user == null){ //代表用户不存在得
            throw new BaseException(LoginConstant.LOGIN_ERROR);
        }
        if(!this.checkPassword(dto.getPassword(),user.getPassword())){ //代表密码错误
            throw new BaseException(LoginConstant.LOGIN_ERROR);
        }
        //密码相等,登录成功
        //获取JWT令牌
        Map<String,Object> claims = new HashMap<>();
        claims.put("id",user.getId());
        String token = JwtUtil.createJWT(claims);

        //构建登录返回
        LoginUserVo loginUserVo = LoginUserVo.builder()
                .userId(user.getId())
                .userName(user.getUserName())
                .roleCode(user.getRoleCode())
                .success(true)
                .msg("登录成功")
                .token(token)
                .build();

        return loginUserVo;
    }

    @Override
    public UserSearchVo pageQuery(UserSearchDto userSearchDto) {
        IPage<UserVo> page = new Page<>(userSearchDto.getPageIndex(),userSearchDto.getPageSize());
        IPage<UserVo> list = userMapper.selectPageVO(page,userSearchDto.getUserName());

        return UserSearchVo.builder()
                .pageIndex(String.valueOf(list.getCurrent()))
                .pageSize(String.valueOf(list.getSize()))
                .totalCount(String.valueOf(list.getTotal()))
                .totalPage(String.valueOf(list.getPages()))
                .currentPageRecords(list.getRecords())
                .build();
    }

    @Override
    public void addUser(UserDto userDto) {
        User user = checkMobile(userDto);
        userMapper.insert(user);
    }

    @Override
    public void updateUser(Integer userId, UserDto userDto) {
        User user = new User();
        BeanUtils.copyProperties(userDto,user);
        user.setId(userId);
        userMapper.updateById(user);
    }

    @Override
    @Transactional
    public void delUser(Integer userId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId,userId);
        User isExist = userMapper.selectOne(queryWrapper);
        if (isExist==null){
            throw new BaseException("用户不存在");
        }
        userMapper.deleteById(userId);
    }

    private User checkMobile(UserDto userDto) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getMobile,userDto.getMobile());
        User isExist = userMapper.selectOne(queryWrapper);
        if (isExist!=null){
            throw new BaseException("该电话号码已绑定账号");
        }
        User user = new User();
        BeanUtils.copyProperties(userDto,user);
        return user;
    }
}
